package com.firefly.admin.login.service.impl;

import com.firefly.admin.common.utils.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.enums.ResultCodeEnum;
import com.firefly.admin.common.exception.BusinessException;
import com.firefly.admin.common.vo.LoginUser;
import com.firefly.admin.system.entity.FySystemMenu;
import com.firefly.admin.system.entity.FySystemRole;
import com.firefly.admin.system.entity.FySystemUser;
import com.firefly.admin.system.service.FySystemMenuService;
import com.firefly.admin.system.service.FySystemRoleService;
import com.firefly.admin.system.service.FySystemUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private FySystemUserService fySystemUserService;
    @Autowired
    private FySystemRoleService fySystemRoleService;
    @Autowired
    private FySystemMenuService fySystemMenuService;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        List<FySystemUser> userList = fySystemUserService.getSystemUserByUserName(userName);
        if (CollectionUtils.isEmpty(userList) || userList.size() != 1) {
            throw new BusinessException(ResultCodeEnum.USER_INFO_EXCEPTION.getMsg());
        }
        FySystemUser fySystemUser = userList.get(0);
        if (!Constants.Status.ENABLE.equals(fySystemUser.getUserStatus())) {
            throw new BusinessException(ResultCodeEnum.LOGIN_NAME_OR_PASSWORD_ERROR.getMsg());
        }
        LoginUser loginUser = new LoginUser();
        LoginUser user = JwtTokenUtil.getLoginUser();
        List<FySystemMenu> systemMenuList = null;
        if (user != null && !CollectionUtils.isEmpty(user.getSystemMenuList())) {
            systemMenuList = user.getSystemMenuList();
        } else {
            List<FySystemRole> roleList = fySystemRoleService.getRoleList(fySystemUser.getUserId());
            if (!CollectionUtils.isEmpty(roleList)) {
                systemMenuList = fySystemMenuService.getMenuListByRoleIds(roleList.stream().map(FySystemRole::getRoleId).collect(Collectors.toList()));
            }
        }
        if (!CollectionUtils.isEmpty(systemMenuList)) {
            String[] menuCodeArray = systemMenuList.stream().filter(Objects::nonNull).map(FySystemMenu::getMenuCode).filter(StringUtils::isNotBlank).toArray(String[]::new);
            List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(menuCodeArray);
            loginUser.setAuthorities(authorities);
        }
        loginUser.setSystemMenuList(systemMenuList);
        loginUser.setUserName(fySystemUser.getUserName());
        loginUser.setLoginPwd(fySystemUser.getLoginPwd());
        loginUser.setFySystemUser(fySystemUser);
        return loginUser;
    }
}
